#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project ：PythonData 
@File    ：ClassicCase.py
@Author  ：朱志文
@Date    ：2021/12/14 10:04 
'''
'''函数练习'''
'''练习1：实现判断一个数是否为素数的函数'''
def is_prime(num):
    '''判断一个数是否为素数'''
    for factor in range(2, int(num ** 0.5) + 1):
        if num % factor == 0:
            return False;
    return True if num != 1 else False;


'''这样写更加容易理解，不过不推荐'''
def is_prime2(num):
    for factor in range(2, num):
        if num % factor == 0:
            return False
    return True if num != 1 else False;


print('判断is_prime函数 {}'.format(is_prime(21)))
print('判断is_prime2函数 {}'.format(is_prime2(21)) )

'''练习2:实现斐波那契数列的第n项数和前n个数。'''

'''写出斐波那契数列第n个'''
def fib_item(n):
    a,b=1,1
    for i in range(n):
        a,b=b,a+b
    return a

print('斐波那契数列第n个数{}'.format(fib_item(10)))

'''写出前n项斐波那契数'''
def fib_topItems(n):
    if n==1:
        return [1]
    if n==2:
        return [1,1]
    fibs=[1,1]
    for i in range(2,n):
        fibs.append(fibs[-1]+fibs[-2])
    return fibs
print('前n项斐波那契数{}'.format(fib_topItems(20)))

'''练习3：打印三角形和菱形'''
'''打印等边三角形'''
def printTriangles(row):
    for i in range(row):
        #第一行的时候有前面有4个空格 第二行有3个空格一次类推
        for _ in range(row-i-1):
            print(' ',end='')
        #第一行的时候有一个星  第二行的时候有三个星
        for _ in range(2*i+1):
            print('*',end='')
        print()
'''打印菱形'''
def printRhombus(row):
    #上三角
    #row等于5 上三角是3=5//2+1
    for i in range(row//2+1):
        # 第一行的时候前面有2个空格 第二行有1个空格以此类推
        for _ in range((row//2+1)-i-1):
            print(' ',end='')
        #第一行的时候有1颗星 第二行的时候有3颗星 以此类推
        for _ in range(2*i+1):
            print('*',end='')
        print()
    #下三角
    #row等于5 下三角是2=5//2
    for i in range(row//2):
        # 第一行的时候有1个空格 第二行有2个空格 以此类推
        for _ in range(i+1):
            print(' ',end='')
        # 第一行的时候有三颗星 第二行的时候有1颗星 最多的星数的一层-2*i
        for _ in range(2*(row//2)-1-2*i):
            print('*',end='')
        print()


printTriangles(5)
printRhombus(11)

'''练习4 分解素数因子'''
def disFactor(num):
    a=2 #最小素数
    while True:
        if num==a:
            print(a)
            break
        if num>a:
            if num%a==0:
                num=num/a
                print(a)
            else:
                a=a+1
disFactor(90)

'''练习5:计算它们的最大公约数和最小公倍数。'''
def divAndMul(x,y):
    if x>y:
        x,y=y,x#如果x大于y的时候 将x与y相互赋值
    for factor in range(x,0,-1):
        if x%factor==0 and y%factor==0:
            print(f'最大公约数是{x,y,factor}')
            print(f'最小公倍数是{x,y,x*y//factor}')
            break
divAndMul(511,292)

'''练习6：水仙花数'''
#说明：水仙花数也被称为超完全数字不变数、自恋数、自幂数、阿姆斯特朗数，它是一个3位数，该数字每个位上数字的立方之和正好等于它本身，例如：$1^3 + 5^3+ 3^3=153$。
def daffCount():
    for num in range(100,999):
        low=num%10
        mid=num//10%10
        high=num//100
        if num==low**3+mid**3+high**3:
            print(num)
daffCount()

def daffCount(nums):
    for num in range(10**(nums-1),10**nums):
        numstr=str(num)
        sum=0
        for i in range(nums):
            sum+=int(numstr[i])**nums
        if sum==num:
            print(num)
daffCount(5)

"""练习7：约瑟夫环问题。
《幸运的基督徒》
有15个基督徒和15个非基督徒在海上遇险，为了能让一部分人活下来不得不将其中15个人扔到海里面去，有个人想了个办法就是大家围成一个圈，由某个人开始从1报数，报到9的人就扔到海里面，他后面的人接着从1开始报数，报到9的人继续扔到海里面，直到扔掉15个人。由于上帝的保佑，15个基督徒都幸免于难，问这些人最开始是怎么站的，哪些位置是基督徒哪些位置是非基督徒。
"""
def main():
    persons = [True] * 30
    counter,index,number=0,0,0 #counter 为基督徒人数 index  number为报号
    while counter<15:
        if persons[index]:
            number+=1
            if number==9:
                persons[index]=False
                counter+=1
                number=0
        index+=1
        index%=30
    for person in persons:
        print('基' if person else '非',end='')
if __name__=='__main__':
    main()















